package com.iot.iotplus.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iot.iotplus.base.Result;
import com.iot.iotplus.entity.MqttUser;
import com.iot.iotplus.entity.Tenant;
import com.iot.iotplus.mapper.MqttUserMapper;
import com.iot.iotplus.mapper.TenantMapper;
import com.iot.iotplus.service.TenantService;
import com.iot.iotplus.utils.ResultUtil;
import com.iot.iotplus.utils.RsaUtils;
import com.iot.iotplus.utils.SnowflakeIdGenerator;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;

import java.io.FileNotFoundException;
import java.security.PrivateKey;
import java.util.Date;
import java.util.Optional;

@Service
public class TenantServiceImpl implements TenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private MqttUserMapper mqttUserMapper;
    @Override
    public Result<?> login(String username, String password, String phoneNumber, String code) {
        QueryWrapper<Tenant> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",username);
        Tenant tenant = tenantMapper.selectOne(queryWrapper);
        String encode = SecureUtil.md5(password);
        //if (tenant == null || !tenant.getPwd().equals(encode) || !SendVerificationCodeUtil.checkCode(phoneNumber,code)) {
        if (tenant == null || !tenant.getPwd().equals(encode) ) {
            return ResultUtil.unverified(null);
        }
        try {
            JwtBuilder jwtBuilder = Jwts.builder();
            String priPath = ResourceUtils.getFile("classpath:pri.txt").getPath();
            PrivateKey privateKey = RsaUtils.getPrivateKey(priPath);
            String token=jwtBuilder.setSubject(tenant.getName())//设置token的主题，即该token所代表的主体。
                    .claim("role","admin") //设置token的声明，即包含了token所包含的属性及其对应的值。
                    .setIssuedAt(new Date())//设置token的签发时间，即token的创建时间。
                    .setId(tenant.getId())//设置token的唯一标识符，通常为一个唯一的字符串。
                    .signWith(privateKey, SignatureAlgorithm.RS256)//使用指定的签名算法和密钥对token进行签名，以确保token的完整性和真实性。
                    .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))// 设置token的过期时间，即token的有效期限，这里是在当前时间的基础上加上3600秒（即1小时）。
                    .compact();
        return ResultUtil.success(token);
        } catch (FileNotFoundException e) {
            return ResultUtil.failed();
        } catch (Exception e) {
            return ResultUtil.failed();
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
    public Result<?> register(Tenant tenant) {
        tenant.setPwd(SecureUtil.md5(tenant.getPwd()));
        tenant.setCreateTime(new Date());
        String id= SnowflakeIdGenerator.getSnowflakeId()+"";
        tenant.setAccessKey(id);
        tenant.setId(id);
        tenant.setAccessSecurity(SecureUtil.md5(tenant.getName()));
        tenant.setDeleted(0);
        tenant.setAuditStatus(1);
        MqttUser mqttUser = new MqttUser(null, id, id, null, 1, new Date(), id);
        int insert1 = mqttUserMapper.insertMqttUser(mqttUser);
        int insert = tenantMapper.insert(tenant);
        if (insert != 1 ||insert1 !=1) {
            return ResultUtil.failed();
        }
        try{
            JwtBuilder jwtBuilder = Jwts.builder();
            String priPath = ResourceUtils.getFile("classpath:pri.txt").getPath();
            PrivateKey privateKey = RsaUtils.getPrivateKey(priPath);
            String token=jwtBuilder.setSubject(tenant.getName())//设置token的主题，即该token所代表的主体。
                    .claim("role","admin") //设置token的声明，即包含了token所包含的属性及其对应的值。
                    .setIssuedAt(new Date())//设置token的签发时间，即token的创建时间。
                    .setId(tenant.getId())//设置token的唯一标识符，通常为一个唯一的字符串。
                    .signWith(privateKey, SignatureAlgorithm.RS256)//使用指定的签名算法和密钥对token进行签名，以确保token的完整性和真实性。
                    .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))// 设置token的过期时间，即token的有效期限，这里是在当前时间的基础上加上3600秒（即1小时）。
                    .compact();
            return ResultUtil.success(token);
        }catch (Exception e){
            return ResultUtil.failed();
        }
    }

    @Override
    public Result<?> add(MqttUser mqttUser) {
        Integer integer = mqttUserMapper.insertMqttUser(mqttUser);
        if (integer != 1) {
            return ResultUtil.failed();
        }
        return ResultUtil.success(integer);
    }

    @Override
    public Result<?> getTenant(String tenant) {
        try {
            Optional.of(tenant);
        }catch (NullPointerException e){
            return ResultUtil.failed();
        }
        Tenant select = tenantMapper.selectById(tenant);
        if (select == null)
            return ResultUtil.failed();
        return ResultUtil.success(select);
    }
}
